package com.econ.powercloud.ems.service.biz;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.econ.powercloud.common.base.facade.enums.StatusType;
import com.econ.powercloud.common.base.facade.exception.CommonRuntimeException;
import com.econ.powercloud.common.base.facade.pojo.MsgResult;
import com.econ.powercloud.common.base.facade.pojo.PageResult;
import com.econ.powercloud.console.facade.domain.*;
import com.econ.powercloud.console.facade.enums.EdgeStrategyTypeEnum;
import com.econ.powercloud.ems.common.enums.*;
import com.econ.powercloud.ems.common.util.IdWorker;
import com.econ.powercloud.ems.constant.SysConstant;
import com.econ.powercloud.ems.dal.entity.EmsDevice;
import com.econ.powercloud.ems.dal.entity.EmsEnergySchedule;
import com.econ.powercloud.ems.dal.entity.EmsPeakShift;
import com.econ.powercloud.ems.dal.entity.EmsPeakShiftDetail;
import com.econ.powercloud.ems.domain.EmsEnergyScheduleDO;
import com.econ.powercloud.ems.domain.EmsPeakShiftDO;
import com.econ.powercloud.ems.domain.EmsPeakShiftDetailDO;
import com.econ.powercloud.ems.pojo.*;
import com.econ.powercloud.ems.pojo.requestVO.EmsEnergyScheduleRequestVO;
import com.econ.powercloud.ems.pojo.requestVO.EmsPeakShiftRequestVO;
import com.econ.powercloud.ems.rpc.IFeignPowerNodeConsoleClient;
import com.econ.powercloud.ems.service.dao.*;
import com.econ.powercloud.ems.util.NetUtils;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zjr
 * @create 2021/7/22 下午4:09
 * @description
 */
@Slf4j
@Service
public class EnergyScheduleService {
    private static final Logger logger = LoggerFactory.getLogger(EnergyScheduleService.class);

    @Autowired
    private IdWorker idWorker;
    @Autowired
    private EmsEnergyScheduleDAO emsEnergyScheduleDAO;
    @Autowired
    private EmsEnergyStationDAO emsEnergyStationDAO;
    @Autowired
    private EmsPeakShiftDAO emsPeakShiftDAO;
    @Autowired
    private EmsPeakShiftDetailDAO emsPeakShiftDetailDAO;
    @Autowired
    private EmsEnergyEquipmentDAO emsEnergyEquipmentDAO;
    @Autowired
    private EmsGlobalIdDAO emsGlobalIdDAO;
    @Autowired
    private EmsDeviceDAO emsDeviceDAO;
    @Autowired
    private IFeignPowerNodeConsoleClient iFeignPowerNodeConsoleClient;
    @Autowired
    private ExtIotNodeDAO extIotNodeDAO;

    public EmsEnergyScheduleVO getEnergyScheduleInfo(String energyStationId, String energyEquipmentId){
        Assert.notNull(emsEnergyStationDAO.getById(energyStationId), FaultDesc.FAILURE_STATION_NON_EXISTENT.getDesc());
        Assert.notNull(emsEnergyEquipmentDAO.getById(energyEquipmentId), FaultDesc.FAILURE_EQUIPMENT_NON_EXISTENT.getDesc());
        EmsEnergySchedule energySchedule = emsEnergyScheduleDAO.getByStationIdByEquipmentId(energyStationId, energyEquipmentId);
        EmsEnergyScheduleVO emsEnergyScheduleVO = EmsEnergyScheduleDO.entityToVO(energySchedule);
        return emsEnergyScheduleVO;
    }

    public PageResult<List<EmsPeakShiftVO>> getPeakShiftList(String energyStationId, String energyEquipmentId, Integer pageNo, Integer pageSize) {
        Page<EmsPeakShift> emsPeakShiftPage = emsPeakShiftDAO.selectPageByStationIdByEquipmentId(energyStationId, energyEquipmentId, pageNo, pageSize);
        return PageResult.<List<EmsPeakShiftVO>>builder().data(EmsPeakShiftDO.entityListToVOList(emsPeakShiftPage.getRecords()))
                .pageNo((int)emsPeakShiftPage.getCurrent()).totalCount((int)emsPeakShiftPage.getTotal()).build();
    }

    @Transactional(rollbackFor = Exception.class)
    public void modifyDemandControl(EmsEnergyScheduleRequestVO emsEnergyScheduleRequestVO) {
        EmsEnergySchedule emsEnergySchedule = emsEnergyScheduleDAO.getByStationIdByEquipmentId(emsEnergyScheduleRequestVO.getEnergyStationId(),emsEnergyScheduleRequestVO.getEnergyEquipmentId());
        LambdaUpdateWrapper<EmsEnergySchedule> emsEnergyScheduleLambdaUpdateWrapper = Wrappers.lambdaUpdate();
        emsEnergyScheduleLambdaUpdateWrapper.eq(EmsEnergySchedule::getEnergyStationId,emsEnergyScheduleRequestVO.getEnergyStationId());
        emsEnergyScheduleLambdaUpdateWrapper.eq(EmsEnergySchedule::getEnergyEquipmentId,emsEnergyScheduleRequestVO.getEnergyEquipmentId());
        emsEnergyScheduleLambdaUpdateWrapper.set(EmsEnergySchedule::getDemandValue,emsEnergyScheduleRequestVO.getDemandValue());
        emsEnergyScheduleLambdaUpdateWrapper.set(EmsEnergySchedule::getDischargePower,emsEnergyScheduleRequestVO.getDischargePower());
        emsEnergyScheduleLambdaUpdateWrapper.set(EmsEnergySchedule::getOverDemandPercent,emsEnergyScheduleRequestVO.getOverDemandPercent());
        modifyEnergySchedule(emsEnergyScheduleRequestVO,emsEnergyScheduleLambdaUpdateWrapper);
        EdgeStrategyRequestVO edgeStrategyRequestVO = setEdgeStrategyRequestVO(emsEnergyScheduleRequestVO , EnergyScheduleType.DEMAND_CONTROL.getCode());
        if(EnabledType.NOT_ENABLE.getCode().equals(emsEnergySchedule.getDemandControlEnabled())){
            return;
        }
        //能量调度下发
        EmsDevice pcsDevice = emsDeviceDAO.getPCSByStationIdAndEquipmentId(emsEnergyScheduleRequestVO.getEnergyStationId(),emsEnergyScheduleRequestVO.getEnergyEquipmentId());
        //检查设备是否挂牌检修(检修则不下发)
        Integer listingType = extIotNodeDAO.selectByNodeId(pcsDevice.getDeviceCode()).getListingType();
        Assert.isTrue(!ListingTypeEnum.OVERHAUL.getCode().equals(listingType),"设备检修中");
        MsgResult<Integer> feignResult = iFeignPowerNodeConsoleClient.strategy(NetUtils.getClientIp(),pcsDevice.getInitDeviceCode(), edgeStrategyRequestVO);
        if(StatusType.OK.getCode() != feignResult.getStatus()){
            throw new CommonRuntimeException(StatusType.FAIL, feignResult.getStatusText());
        }
        logger.info("更新需量控制信息:时间:"+System.currentTimeMillis() + ",VO:"+JSON.toJSONString(edgeStrategyRequestVO));
    }

    @Transactional(rollbackFor = Exception.class)
    public void modifyBackupPower(EmsEnergyScheduleRequestVO emsEnergyScheduleRequestVO) {
        EmsEnergySchedule emsEnergySchedule = emsEnergyScheduleDAO.getByStationIdByEquipmentId(emsEnergyScheduleRequestVO.getEnergyStationId(),emsEnergyScheduleRequestVO.getEnergyEquipmentId());
        LambdaUpdateWrapper<EmsEnergySchedule> emsEnergyScheduleLambdaUpdateWrapper = Wrappers.lambdaUpdate();
        emsEnergyScheduleLambdaUpdateWrapper.eq(EmsEnergySchedule::getEnergyStationId,emsEnergyScheduleRequestVO.getEnergyStationId());
        emsEnergyScheduleLambdaUpdateWrapper.eq(EmsEnergySchedule::getEnergyEquipmentId,emsEnergyScheduleRequestVO.getEnergyEquipmentId());
        emsEnergyScheduleLambdaUpdateWrapper.set(EmsEnergySchedule::getBatteryReservedCapacity,emsEnergyScheduleRequestVO.getBatteryReservedCapacity());
        modifyEnergySchedule(emsEnergyScheduleRequestVO,emsEnergyScheduleLambdaUpdateWrapper);
        EdgeStrategyRequestVO edgeStrategyRequestVO = setEdgeStrategyRequestVO(emsEnergyScheduleRequestVO , EnergyScheduleType.BACKUP_POWER.getCode());
        if (EnabledType.NOT_ENABLE.getCode().equals(emsEnergySchedule.getBackupPowerEnabled())){
            return;
        }
        //检查设备是否挂牌检修(检修则不下发)
        EmsDevice pscDevice = emsDeviceDAO.getPCSByStationIdAndEquipmentId(emsEnergyScheduleRequestVO.getEnergyStationId(),emsEnergyScheduleRequestVO.getEnergyEquipmentId());
        Integer listingType = extIotNodeDAO.selectByNodeId(pscDevice.getDeviceCode()).getListingType();
        Assert.isTrue(!ListingTypeEnum.OVERHAUL.getCode().equals(listingType),"设备检修中");
        // 能量调度下发
        MsgResult<Integer> feignResult = iFeignPowerNodeConsoleClient.strategy(NetUtils.getClientIp(),emsDeviceDAO.getPCSByStationIdAndEquipmentId(emsEnergyScheduleRequestVO.getEnergyStationId(),emsEnergyScheduleRequestVO.getEnergyEquipmentId()).getInitDeviceCode(),edgeStrategyRequestVO);
        if(StatusType.OK.getCode() != feignResult.getStatus()){
            throw new CommonRuntimeException(StatusType.FAIL, feignResult.getStatusText());
        }
        logger.info("更新后备电源信息:时间:"+System.currentTimeMillis() + ",VO:"+JSON.toJSONString(edgeStrategyRequestVO));
    }

    @Transactional(rollbackFor = Exception.class)
    public void modifySocControl(EmsEnergyScheduleRequestVO requestVO) {
        //判断更新SOC控制的参数是否正确
        Assert.isTrue(requestVO.getSocLower() > 0.0,"SOC下限应大于0!");
        Assert.isTrue(requestVO.getUsableSocLower() >= requestVO.getSocLower(),"SOC可用下限应大于等于SOC下限");
        Assert.isTrue(requestVO.getUsableSocUpper() > requestVO.getUsableSocLower(),"SOC可用上限应大于可用SOC下限");
        Assert.isTrue(requestVO.getSocUpper() >= requestVO.getUsableSocUpper(),"SOC上限应大于等于可用SOC上限");
        Assert.isTrue(requestVO.getSocUpper() < 100.0,"SOC上限应小于100");

        EmsEnergySchedule emsEnergySchedule = emsEnergyScheduleDAO.getByStationIdByEquipmentId(requestVO.getEnergyStationId(),requestVO.getEnergyEquipmentId());
        LambdaUpdateWrapper<EmsEnergySchedule> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(EmsEnergySchedule::getEnergyStationId,requestVO.getEnergyStationId());
        wrapper.eq(EmsEnergySchedule::getEnergyEquipmentId,requestVO.getEnergyEquipmentId());
        wrapper.set(EmsEnergySchedule::getSocUpper,requestVO.getSocUpper());
        wrapper.set(EmsEnergySchedule::getSocLower,requestVO.getSocLower());
        wrapper.set(EmsEnergySchedule::getUsableSocUpper,requestVO.getUsableSocUpper());
        wrapper.set(EmsEnergySchedule::getUsableSocLower,requestVO.getUsableSocLower());
        wrapper.set(EmsEnergySchedule::getEnableInputSocMaintain,requestVO.getEnableInputSocMaintain());
        this.modifyEnergySchedule(requestVO,wrapper);
        EdgeStrategyRequestVO edgeStrategyRequestVO = setEdgeStrategyRequestVO(requestVO , EnergyScheduleType.SOC_CONTROL.getCode());

        if (EnabledType.NOT_ENABLE.getCode().equals(emsEnergySchedule.getSocControlEnabled())){
            return;
        }
        //检查设备检修状态
        EmsDevice pscDevice = emsDeviceDAO.getPCSByStationIdAndEquipmentId(requestVO.getEnergyStationId(),requestVO.getEnergyEquipmentId());
        Integer listingType = extIotNodeDAO.selectByNodeId(pscDevice.getDeviceCode()).getListingType();
        Assert.isTrue(!ListingTypeEnum.OVERHAUL.getCode().equals(listingType),"设备检修中");
        // 能量调度下发
        MsgResult<Integer> feignResult = iFeignPowerNodeConsoleClient.strategy(NetUtils.getClientIp(),
                emsDeviceDAO.getPCSByStationIdAndEquipmentId(requestVO.getEnergyStationId(),requestVO.getEnergyEquipmentId()).getInitDeviceCode(),edgeStrategyRequestVO);
        if(StatusType.OK.getCode() != feignResult.getStatus()){
            throw new CommonRuntimeException(StatusType.FAIL, feignResult.getStatusText());
        }
        logger.info("更新SOC控制信息:时间:"+System.currentTimeMillis() + ",VO:"+JSON.toJSONString(edgeStrategyRequestVO));
    }

    @Transactional(rollbackFor = Exception.class)
    public void modifyInversePowerOutput(EmsEnergyScheduleRequestVO emsEnergyScheduleRequestVO) {
        EmsEnergySchedule emsEnergySchedule = emsEnergyScheduleDAO.getByStationIdByEquipmentId(emsEnergyScheduleRequestVO.getEnergyStationId(),emsEnergyScheduleRequestVO.getEnergyEquipmentId());
        LambdaUpdateWrapper<EmsEnergySchedule> emsEnergyScheduleLambdaUpdateWrapper = Wrappers.lambdaUpdate();
        emsEnergyScheduleLambdaUpdateWrapper.eq(EmsEnergySchedule::getEnergyStationId,emsEnergyScheduleRequestVO.getEnergyStationId());
        emsEnergyScheduleLambdaUpdateWrapper.eq(EmsEnergySchedule::getEnergyEquipmentId,emsEnergyScheduleRequestVO.getEnergyEquipmentId());
        emsEnergyScheduleLambdaUpdateWrapper.set(EmsEnergySchedule::getInversePowerMinPower,emsEnergyScheduleRequestVO.getInversePowerMinPower());
        modifyEnergySchedule(emsEnergyScheduleRequestVO,emsEnergyScheduleLambdaUpdateWrapper);
        EdgeStrategyRequestVO edgeStrategyRequestVO = setEdgeStrategyRequestVO(emsEnergyScheduleRequestVO , EnergyScheduleType.INVERSE_POWER_OUTPUT.getCode());
        if (EnabledType.NOT_ENABLE.getCode().equals(emsEnergySchedule.getInversePowerOutputEnabled())){
            return;
        }
        //检查设备检修状态
        EmsDevice pscDevice = emsDeviceDAO.getPCSByStationIdAndEquipmentId(emsEnergyScheduleRequestVO.getEnergyStationId(),emsEnergyScheduleRequestVO.getEnergyEquipmentId());
        Integer listingType = extIotNodeDAO.selectByNodeId(pscDevice.getDeviceCode()).getListingType();
        Assert.isTrue(!ListingTypeEnum.OVERHAUL.getCode().equals(listingType),"设备检修中");
        // 能量调度下发
        MsgResult<Integer> feignResult = iFeignPowerNodeConsoleClient.strategy(NetUtils.getClientIp(),emsDeviceDAO.getPCSByStationIdAndEquipmentId(emsEnergyScheduleRequestVO.getEnergyStationId(),emsEnergyScheduleRequestVO.getEnergyEquipmentId()).getInitDeviceCode(),edgeStrategyRequestVO);
        if(StatusType.OK.getCode() != feignResult.getStatus()){
            throw new CommonRuntimeException(StatusType.FAIL, feignResult.getStatusText());
        }
        logger.info("更新功率反送信息:时间:"+System.currentTimeMillis() + ",VO:"+JSON.toJSONString(edgeStrategyRequestVO));
    }

    public void modifyEnergySchedule(EmsEnergyScheduleRequestVO emsEnergyScheduleRequestVO,LambdaUpdateWrapper<EmsEnergySchedule> emsEnergyScheduleLambdaUpdateWrapper) {
        Assert.notNull(emsEnergyScheduleRequestVO.getEnergyStationId(), FaultDesc.FAILURE_STATION_CODE_EMPTY.getDesc());
        Assert.notNull(emsEnergyScheduleRequestVO.getEnergyEquipmentId(), FaultDesc.FAILURE_EQUIPMENT_CODE_EMPTY.getDesc());
        EmsEnergySchedule byStationIdByEquipmentId = emsEnergyScheduleDAO.getByStationIdByEquipmentId(emsEnergyScheduleRequestVO.getEnergyStationId(), emsEnergyScheduleRequestVO.getEnergyEquipmentId());
        emsEnergyScheduleDAO.update(byStationIdByEquipmentId,emsEnergyScheduleLambdaUpdateWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    public void addDefaultEnergySchedule(String energyStationId, String energyEquipmentId) {
        Assert.notNull(energyStationId, FaultDesc.FAILURE_STATION_CODE_EMPTY.getDesc());
        Assert.notNull(energyEquipmentId, FaultDesc.FAILURE_EQUIPMENT_NON_EXISTENT.getDesc());
        emsEnergyScheduleDAO.addEnergySchedule(EmsEnergySchedule.builder().energyStationId(energyStationId).energyEquipmentId(energyEquipmentId)
                .demandValue(1600.0).overDemandPercent(90.0).dischargePower(100.0).demandControlEnabled(EnabledType.NOT_ENABLE.getCode())
                .batteryReservedCapacity(20.0).backupPowerEnabled(EnabledType.NOT_ENABLE.getCode())
                .socUpper(100.0).socLower(10.0).usableSocUpper(80.0).usableSocUpper(20.0).enableInputSocMaintain(1)
                .socControlEnabled(EnabledType.NOT_ENABLE.getCode())
                .inversePowerOutputEnabled(EnabledType.NOT_ENABLE.getCode()).inversePowerMinPower(20.00).build());
        String peakShiftId = String.valueOf(emsGlobalIdDAO.getGlobalId());
        emsPeakShiftDAO.save(EmsPeakShift.builder().energyStationId(energyStationId).energyEquipmentId(energyEquipmentId).peakShiftId(peakShiftId)
                .peakShiftName(SysConstant.DEFAULT_STRATEGY).peakShiftEnabled(EnabledType.NOT_ENABLE.getCode())
                .gmtCreate(LocalDateTime.now()).gmtModify(LocalDateTime.now()).build());
        List<EmsPeakShiftDetail> emsPeakShiftDetails = Lists.newArrayList();
        emsPeakShiftDetails.add(EmsPeakShiftDetail.builder().peakShiftId(peakShiftId).chargeDischarge(ChargeDischargeType.CHARGE.getCode()).power(75.0).startTime(0).endTime(420).build());
        emsPeakShiftDetails.add(EmsPeakShiftDetail.builder().peakShiftId(peakShiftId).chargeDischarge(ChargeDischargeType.STANBY.getCode()).power(0.0).startTime(420).endTime(510).build());
        emsPeakShiftDetails.add(EmsPeakShiftDetail.builder().peakShiftId(peakShiftId).chargeDischarge(ChargeDischargeType.DISCHARGE.getCode()).power(-70.0).startTime(510).endTime(690).build());
        emsPeakShiftDetails.add(EmsPeakShiftDetail.builder().peakShiftId(peakShiftId).chargeDischarge(ChargeDischargeType.STANBY.getCode()).power(0.0).startTime(690).endTime(1080).build());
        emsPeakShiftDetails.add(EmsPeakShiftDetail.builder().peakShiftId(peakShiftId).chargeDischarge(ChargeDischargeType.DISCHARGE.getCode()).power(-70.0).startTime(1080).endTime(1380).build());
        emsPeakShiftDetails.add(EmsPeakShiftDetail.builder().peakShiftId(peakShiftId).chargeDischarge(ChargeDischargeType.CHARGE.getCode()).power(75.0).startTime(1380).endTime(1440).build());
        emsPeakShiftDetailDAO.addPeakShiftDetailList(emsPeakShiftDetails);
    }

    @Transactional(rollbackFor = Exception.class)
    public EmsPeakShift addPeakShift(EmsPeakShiftRequestVO emsPeakShiftRequestVO){
        Assert.notNull(emsPeakShiftRequestVO.getEnergyStationId(), FaultDesc.FAILURE_STATION_CODE_EMPTY.getDesc());
        //判断策略名称是否重复
        List<EmsPeakShift> shiftList = emsPeakShiftDAO.selectListByStationIdByEquipmentId(emsPeakShiftRequestVO.getEnergyStationId(),emsPeakShiftRequestVO.getEnergyEquipmentId());
        List<String> shiftNameList = shiftList.stream().map(EmsPeakShift::getPeakShiftName).collect(Collectors.toList());
        if(shiftNameList.contains(emsPeakShiftRequestVO.getPeakShiftName())){
            throw new CommonRuntimeException(StatusType.FAIL, FaultDesc.FAILURE_PEAK_SHIFT_NAME_REPEAT.getDesc());
        }
        String peakShiftId = String.valueOf(idWorker.nextId());
        EmsPeakShift emsPeakShift = EmsPeakShiftDO.requestVOToEntity(emsPeakShiftRequestVO);
        emsPeakShift.setPeakShiftEnabled(EnabledType.NOT_ENABLE.getCode());
        emsPeakShift.setGmtCreate(LocalDateTime.now());
        emsPeakShift.setGmtModify(LocalDateTime.now());
        emsPeakShift.setPeakShiftId(peakShiftId);
        emsPeakShiftDAO.save(emsPeakShift);
        List<EmsPeakShiftDetail> emsPeakShiftDetails = EmsPeakShiftDetailDO.requestVOListToEntityList(emsPeakShiftRequestVO.getEmsPeakShiftDetailRequestVOS());
        emsPeakShiftDetails.forEach(detail->{
            detail.setPeakShiftId(peakShiftId);
        });
        emsPeakShiftDetails = judgeAndFixPeakShiftTime(emsPeakShiftDetails);
        emsPeakShiftDetailDAO.addPeakShiftDetailList(emsPeakShiftDetails);
        return emsPeakShift;
    }

    @Transactional(rollbackFor = Exception.class)
    public EmsPeakShift modifyPeakShift(EmsPeakShiftRequestVO emsPeakShiftRequestVO) {
        if (emsPeakShiftDAO.getById(emsPeakShiftRequestVO.getPeakShiftId())==null){
            throw new CommonRuntimeException(StatusType.INVALID_REQUEST, FaultDesc.FAILURE_PEAK_SHIFT_NOT_EXISTS.getDesc());
        }
        EmsPeakShift byId = emsPeakShiftDAO.getById(emsPeakShiftRequestVO.getPeakShiftId());
        Integer peakShiftEnabled = byId.getPeakShiftEnabled();
        emsPeakShiftRequestVO.setPeakShiftEnabled(peakShiftEnabled);
        EdgeStrategyRequestVO edgeStrategyRequestVO = setEmsPeakShiftReportedVO(emsPeakShiftRequestVO);
        EmsPeakShift emsPeakShift = EmsPeakShiftDO.requestVOToEntity(emsPeakShiftRequestVO);
        emsPeakShift.setGmtModify(LocalDateTime.now());
        emsPeakShiftDAO.updateById(emsPeakShift);
        List<EmsPeakShiftDetail> emsPeakShiftDetails = EmsPeakShiftDetailDO.requestVOListToEntityList(emsPeakShiftRequestVO.getEmsPeakShiftDetailRequestVOS());
        emsPeakShiftDetails = judgeAndFixPeakShiftTime(emsPeakShiftDetails);
        emsPeakShiftDetailDAO.removeByPeakShiftId(emsPeakShift.getPeakShiftId());
        emsPeakShiftDetailDAO.addPeakShiftDetailList(emsPeakShiftDetails);
        /**
         * 策略在用状态修改
         */
        if (EnabledType.ENABLE.getCode().equals(peakShiftEnabled)) {
            if (EnabledType.ENABLE.getCode().equals(emsPeakShiftRequestVO.getPeakShiftEnabled())){
                //检查设备检修状态
                EmsDevice pscDevice = emsDeviceDAO.getPCSByStationIdAndEquipmentId(emsPeakShift.getEnergyStationId(),emsPeakShift.getEnergyEquipmentId());
                Integer listingType = extIotNodeDAO.selectByNodeId(pscDevice.getDeviceCode()).getListingType();
                Assert.isTrue(!ListingTypeEnum.OVERHAUL.getCode().equals(listingType),"设备检修中");
                //能量调度下发
                MsgResult<Integer> feignResult = iFeignPowerNodeConsoleClient.strategy(NetUtils.getClientIp(),emsDeviceDAO.getPCSByStationIdAndEquipmentId(emsPeakShift.getEnergyStationId(),emsPeakShift.getEnergyEquipmentId()).getInitDeviceCode(),edgeStrategyRequestVO);
                if(StatusType.OK.getCode() != feignResult.getStatus()){
                    throw new CommonRuntimeException(StatusType.FAIL, feignResult.getStatusText());
                }
                logger.info("修改移峰填谷策略:时间:"+System.currentTimeMillis() + ",VO:"+JSON.toJSONString(edgeStrategyRequestVO));
            }
            return  emsPeakShift;
        }
        /**
         * 非在用状态，比对原状态，发生改变则下发命令
         */
        if(!peakShiftEnabled.equals(emsPeakShiftRequestVO.getPeakShiftEnabled())){
            //检查设备检修状态
            EmsDevice pscDevice = emsDeviceDAO.getPCSByStationIdAndEquipmentId(emsPeakShift.getEnergyStationId(),emsPeakShift.getEnergyEquipmentId());
            Integer listingType = extIotNodeDAO.selectByNodeId(pscDevice.getDeviceCode()).getListingType();
            Assert.isTrue(!ListingTypeEnum.OVERHAUL.getCode().equals(listingType),"设备检修中");
            //能量调度下发
            MsgResult<Integer> feignResult = iFeignPowerNodeConsoleClient.strategy(NetUtils.getClientIp(),emsDeviceDAO.getPCSByStationIdAndEquipmentId(emsPeakShift.getEnergyStationId(),emsPeakShift.getEnergyEquipmentId()).getInitDeviceCode(),edgeStrategyRequestVO);
            if(StatusType.OK.getCode() != feignResult.getStatus()){
                throw new CommonRuntimeException(StatusType.FAIL, feignResult.getStatusText());
            }
            logger.info("修改移峰填谷策略:时间:"+System.currentTimeMillis() + ",VO:"+JSON.toJSONString(edgeStrategyRequestVO));
        }
        return emsPeakShift;
    }

    @Transactional(rollbackFor = Exception.class)
    public void deletePeakShift(String peakShiftId) {
        if(EnabledType.ENABLE.getCode().equals(emsPeakShiftDAO.getById(peakShiftId).getPeakShiftEnabled())){
            throw new CommonRuntimeException(StatusType.INVALID_REQUEST, FaultDesc.FAILURE_PEAK_SHIFT_IN_USED.getDesc());
        }
        emsPeakShiftDAO.removeById(peakShiftId);
        emsPeakShiftDetailDAO.removeByPeakShiftId(peakShiftId);
    }

    public List<EmsPeakShiftDetailVO> getPeakShiftInfo(String peakShiftId) {
        List<EmsPeakShiftDetail> emsPeakShiftDetails = emsPeakShiftDetailDAO.getListByPeakShiftId(peakShiftId);
        return EmsPeakShiftDetailDO.entityListToVOList(emsPeakShiftDetails);
    }

    @Transactional(rollbackFor = Exception.class)
    public void demandControlEnabled(String energyStationId, String energyEquipmentId, Integer enabled) {
        EmsEnergySchedule emsEnergySchedule = emsEnergyScheduleDAO.getByStationIdByEquipmentId(energyStationId, energyEquipmentId);
        emsEnergyScheduleDAO.demandControlEnabled(emsEnergySchedule,enabled);
        if (!enabled.equals(emsEnergySchedule.getDemandControlEnabled())){
            EdgeStrategyRequestVO requestVO = setEnergyScheduleEnableReportedVO(energyStationId,energyEquipmentId,enabled, EnergyScheduleType.DEMAND_CONTROL.getCode());
            //检查设备检修状态
            EmsDevice pscDevice = emsDeviceDAO.getPCSByStationIdAndEquipmentId(energyStationId, energyEquipmentId);
            Integer listingType = extIotNodeDAO.selectByNodeId(pscDevice.getDeviceCode()).getListingType();
            Assert.isTrue(!ListingTypeEnum.OVERHAUL.getCode().equals(listingType),"设备检修中");
            //能量调度下发
            MsgResult<Integer> feignResult = iFeignPowerNodeConsoleClient.strategy(NetUtils.getClientIp(),emsDeviceDAO.getPCSByStationIdAndEquipmentId(energyStationId, energyEquipmentId).getInitDeviceCode(),requestVO);
            if(StatusType.OK.getCode() != feignResult.getStatus()){
                throw new CommonRuntimeException(StatusType.FAIL, feignResult.getStatusText());
            }
            logger.info("启用/停用需量控制:时间:"+System.currentTimeMillis() + ",VO:"+JSON.toJSONString(requestVO));
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void backupPowerEnabled(String energyStationId, String energyEquipmentId, Integer enabled) {
        EmsEnergySchedule emsEnergySchedule = emsEnergyScheduleDAO.getByStationIdByEquipmentId(energyStationId, energyEquipmentId);
        emsEnergyScheduleDAO.backupPowerEnabled(emsEnergySchedule,enabled);
        if (!enabled.equals(emsEnergySchedule.getBackupPowerEnabled())){
            EdgeStrategyRequestVO requestVO = setEnergyScheduleEnableReportedVO(energyStationId,energyEquipmentId,enabled, EnergyScheduleType.BACKUP_POWER.getCode());
            //检查设备检修状态
            EmsDevice pscDevice = emsDeviceDAO.getPCSByStationIdAndEquipmentId(energyStationId, energyEquipmentId);
            Integer listingType = extIotNodeDAO.selectByNodeId(pscDevice.getDeviceCode()).getListingType();
            Assert.isTrue(!ListingTypeEnum.OVERHAUL.getCode().equals(listingType),"设备检修中");
            //能量调度下发
            MsgResult<Integer> feignResult = iFeignPowerNodeConsoleClient.strategy(NetUtils.getClientIp(),emsDeviceDAO.getPCSByStationIdAndEquipmentId(energyStationId, energyEquipmentId).getInitDeviceCode(), requestVO);
            if(StatusType.OK.getCode() != feignResult.getStatus()){
                throw new CommonRuntimeException(StatusType.FAIL, feignResult.getStatusText());
            }
            logger.info("启用/停用后备电源:时间:"+System.currentTimeMillis() + ",VO:"+JSON.toJSONString(requestVO));
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void socControlEnabled(String energyStationId, String energyEquipmentId, Integer enabled) {
        EmsEnergySchedule emsEnergySchedule = emsEnergyScheduleDAO.getByStationIdByEquipmentId(energyStationId, energyEquipmentId);
        emsEnergyScheduleDAO.updateSocControlEnable(emsEnergySchedule,enabled);
        if (!enabled.equals(emsEnergySchedule.getSocControlEnabled())){
            EdgeStrategyRequestVO requestVO = setEnergyScheduleEnableReportedVO(energyStationId,energyEquipmentId,enabled, EnergyScheduleType.SOC_CONTROL.getCode());
            //检查设备检修状态
            EmsDevice pscDevice = emsDeviceDAO.getPCSByStationIdAndEquipmentId(energyStationId, energyEquipmentId);
            Integer listingType = extIotNodeDAO.selectByNodeId(pscDevice.getDeviceCode()).getListingType();
            Assert.isTrue(!ListingTypeEnum.OVERHAUL.getCode().equals(listingType),"设备检修中");
            //能量调度下发
            MsgResult<Integer> feignResult = iFeignPowerNodeConsoleClient.strategy(NetUtils.getClientIp(),emsDeviceDAO.getPCSByStationIdAndEquipmentId(energyStationId, energyEquipmentId).getInitDeviceCode(), requestVO);
            if(StatusType.OK.getCode() != feignResult.getStatus()){
                throw new CommonRuntimeException(StatusType.FAIL, feignResult.getStatusText());
            }
            logger.info("启用/停用后备电源:时间:"+System.currentTimeMillis() + ",VO:"+JSON.toJSONString(requestVO));
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void inversePowerOutputEnabled(String energyStationId, String energyEquipmentId, Integer enabled) {
        EmsEnergySchedule emsEnergySchedule = emsEnergyScheduleDAO.getByStationIdByEquipmentId(energyStationId, energyEquipmentId);
        emsEnergyScheduleDAO.inversePowerOutputEnabled(emsEnergySchedule,enabled);
        if (!enabled.equals(emsEnergySchedule.getInversePowerOutputEnabled())){
            EdgeStrategyRequestVO requestVO = setEnergyScheduleEnableReportedVO(energyStationId,energyEquipmentId,enabled, EnergyScheduleType.INVERSE_POWER_OUTPUT.getCode());
            //检查设备检修状态
            EmsDevice pscDevice = emsDeviceDAO.getPCSByStationIdAndEquipmentId(energyStationId, energyEquipmentId);
            Integer listingType = extIotNodeDAO.selectByNodeId(pscDevice.getDeviceCode()).getListingType();
            Assert.isTrue(!ListingTypeEnum.OVERHAUL.getCode().equals(listingType),"设备检修中");
            //能量调度下发
            MsgResult<Integer> feignResult = iFeignPowerNodeConsoleClient.strategy(NetUtils.getClientIp(),emsDeviceDAO.getPCSByStationIdAndEquipmentId(energyStationId, energyEquipmentId).getInitDeviceCode(), requestVO);
            if(StatusType.OK.getCode() != feignResult.getStatus()){
                throw new CommonRuntimeException(StatusType.FAIL, feignResult.getStatusText());
            }
            logger.info("启用/停用功率反送:时间:"+System.currentTimeMillis() + ",VO:"+JSON.toJSONString(requestVO));
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public Pair<Integer, String> peakShiftEnabled(String peakShiftId, Integer enabled) {
        EmsPeakShift emsPeakShift = emsPeakShiftDAO.getById(peakShiftId);
        Integer peakShiftEnabled = emsPeakShift.getPeakShiftEnabled();
        String energyStationId = emsPeakShift.getEnergyStationId();
        String energyEquipmentId = emsPeakShift.getEnergyEquipmentId();
        emsPeakShiftDAO.batchModifyEnableByStationIdAndEquipmentId(energyStationId,energyEquipmentId, EnabledType.NOT_ENABLE.getCode());
        emsPeakShift.setPeakShiftEnabled(enabled);
        emsPeakShiftDAO.updateById(emsPeakShift);
        if(!enabled.equals(peakShiftEnabled)){
            EdgeStrategyRequestVO requestVO = setEmsPeakShiftEnableReportedVO(peakShiftId,enabled);
            String strategy = JSON.toJSONString(requestVO);
            //检查设备检修状态
            EmsDevice pscDevice = emsDeviceDAO.getPCSByStationIdAndEquipmentId(energyStationId, energyEquipmentId);
            Integer listingType = extIotNodeDAO.selectByNodeId(pscDevice.getDeviceCode()).getListingType();
            Assert.isTrue(!ListingTypeEnum.OVERHAUL.getCode().equals(listingType),"设备检修中");
            //能量调度下发
            MsgResult<Integer> feignResult = iFeignPowerNodeConsoleClient.strategy(NetUtils.getClientIp(),emsDeviceDAO.getPCSByStationIdAndEquipmentId(energyStationId, energyEquipmentId).getInitDeviceCode(), requestVO);
            if(StatusType.OK.getCode() != feignResult.getStatus()){
                throw new CommonRuntimeException(StatusType.FAIL, feignResult.getStatusText());
            }
            logger.info("启用/停用移峰填谷:时间:"+System.currentTimeMillis() + ",VO:"+JSON.toJSONString(requestVO));
            return Pair.of(feignResult.getData(), strategy);
        }
        return null;
    }

    /**
     *校验移峰填谷策略的时间
     * @param emsPeakShiftDetails
     * @return
     */
    public List<EmsPeakShiftDetail> judgeAndFixPeakShiftTime(List<EmsPeakShiftDetail> emsPeakShiftDetails){
        Integer endTime ;  //前一结束时间
        Integer startTime ;  //前一起始时间
        Integer laterStartTime ;  //后一起始时间
        Integer laterEndTime ; //后一结束时间
        List<EmsPeakShiftDetail> list = new ArrayList<>();
        for(int i =0;i<emsPeakShiftDetails.size();i++){
            startTime = emsPeakShiftDetails.get(i).getStartTime();
            endTime = emsPeakShiftDetails.get(i).getEndTime();
            if (startTime >= endTime) {
                throw new CommonRuntimeException(StatusType.INVALID_REQUEST, FaultDesc.FAILURE_PEAK_SHIFT_TIME_FAULSE.getDesc());
            }
        }
        /**
         * 开始以起始时间排序
         */
        emsPeakShiftDetails = sortEmsPeakShiftDetail(emsPeakShiftDetails);

        /**
         * 最初起始时间是否从0开始
         */
        if (!emsPeakShiftDetails.get(0).getStartTime().equals(0)){
            EmsPeakShiftDetail emsPeakShiftDetail = EmsPeakShiftDetail.builder().peakShiftId(emsPeakShiftDetails.get(0).getPeakShiftId()).
                    chargeDischarge(ChargeDischargeType.STANBY.getCode()).power(SysConstant.POWER).startTime(SysConstant.STRATEGY_DEFAULT_STARTTIME).endTime(emsPeakShiftDetails.get(0).getStartTime()).build();
            emsPeakShiftDetails.add(0,emsPeakShiftDetail);
        }
        /**
         * i的最大值小于size-2是为了避免产生下标越界
         */
        int num = 0;
        list.addAll(emsPeakShiftDetails);
        for(int i =0;i<emsPeakShiftDetails.size()-1;i++){
            endTime = emsPeakShiftDetails.get(i).getEndTime();
            laterStartTime = emsPeakShiftDetails.get(i+1).getStartTime();
            /**
             * 后一起始时间是否大于、小于前一结束时间
             */
            if (laterStartTime<endTime){
                throw new CommonRuntimeException(StatusType.INVALID_REQUEST, FaultDesc.FAILURE_PEAK_SHIFT_TIME_FAULSE.getDesc());
            }else if (laterStartTime>endTime){
                EmsPeakShiftDetail emsPeakShiftDetail = EmsPeakShiftDetail.builder().peakShiftId(emsPeakShiftDetails.get(0).getPeakShiftId()).
                        chargeDischarge(ChargeDischargeType.STANBY.getCode()).power(SysConstant.POWER).
                        startTime(endTime).endTime(laterStartTime).build();
                list.add(i+1+num,emsPeakShiftDetail);
                num++;
            }
        }
        emsPeakShiftDetails = list;
        /**
         * 最后截止时间是否等于24点
         */
        if (emsPeakShiftDetails.get(emsPeakShiftDetails.size()-1).getEndTime()< SysConstant.MAX_PEAKSHIFT_MINUTE){
            EmsPeakShiftDetail emsPeakShiftDetail = EmsPeakShiftDetail.builder().peakShiftId(emsPeakShiftDetails.get(0).getPeakShiftId())
                    .chargeDischarge(ChargeDischargeType.STANBY.getCode()).power(SysConstant.POWER).startTime(emsPeakShiftDetails.get(emsPeakShiftDetails.size()-1).getEndTime())
                    .endTime(SysConstant.MAX_PEAKSHIFT_MINUTE).build();
            emsPeakShiftDetails.add(emsPeakShiftDetail);
        }
        List<EmsPeakShiftDetail> result = new ArrayList<>();
        for (int i = 0; i < list.size() -1 ; i++){
            EmsPeakShiftDetail firstDetail = list.get(i);
            EmsPeakShiftDetail lastDetail = list.get(i+1);
            if(firstDetail.getPower().equals(lastDetail.getPower())){
                list.get(i+1).setStartTime(list.get(i).getStartTime());
                continue;
            }
            result.add(firstDetail);
        }
        result.add(list.get(list.size()-1));
        return result;
    }


    public EdgeStrategyRequestVO setEdgeStrategyRequestVO(EmsEnergyScheduleRequestVO emsEnergyScheduleRequestVO , Integer type){
        EdgeStrategyRequestVO edgeStrategyRequestVO = new EdgeStrategyRequestVO();
        /**
         * 开始判断前端调用的能量调度的哪个接口
         */
        if(type.equals(EnergyScheduleType.DEMAND_CONTROL.getCode())){
            /**
             * 进入需量控制下发
             */
            EdgeStrategyDemandControl edgeStrategyDemandControl = new EdgeStrategyDemandControl();
            edgeStrategyDemandControl.setDemandValue(emsEnergyScheduleRequestVO.getDemandValue());
            edgeStrategyDemandControl.setOverDemandPercent(emsEnergyScheduleRequestVO.getOverDemandPercent());
            edgeStrategyDemandControl.setDischargePower(emsEnergyScheduleRequestVO.getDischargePower());

            edgeStrategyRequestVO.setEnable(emsEnergyScheduleRequestVO.getDemandControlEnabled());
            edgeStrategyRequestVO.setType(EdgeStrategyTypeEnum.DEMAND_CONTOL.getCode());
            edgeStrategyRequestVO.setDesc(EdgeStrategyTypeEnum.DEMAND_CONTOL.getDesc());
            edgeStrategyRequestVO.setData(edgeStrategyDemandControl);
        }else if(type.equals(EnergyScheduleType.BACKUP_POWER.getCode())){
            /**
             * 进入后备电源下发
             */
            EdgeStrategyBatteryReserved batteryReserved = new EdgeStrategyBatteryReserved();
            batteryReserved.setBatteryReservedCapacity(emsEnergyScheduleRequestVO.getBatteryReservedCapacity());

            edgeStrategyRequestVO.setEnable(emsEnergyScheduleRequestVO.getBackupPowerEnabled());
            edgeStrategyRequestVO.setType(EdgeStrategyTypeEnum.BATTERY_RESERVED.getCode());
            edgeStrategyRequestVO.setDesc(EdgeStrategyTypeEnum.BATTERY_RESERVED.getDesc());
            edgeStrategyRequestVO.setData(batteryReserved);
        }else if(type.equals(EnergyScheduleType.INVERSE_POWER_OUTPUT.getCode())){
            /**
             * 进入反功率倒送下发
             */
            EdgeStrategyReversePower reversePower = new EdgeStrategyReversePower();
            reversePower.setInversePowerMinPower(emsEnergyScheduleRequestVO.getInversePowerMinPower());

            edgeStrategyRequestVO.setEnable(emsEnergyScheduleRequestVO.getInversePowerOutputEnabled());
            edgeStrategyRequestVO.setType(EdgeStrategyTypeEnum.REVERSE_POWER.getCode());
            edgeStrategyRequestVO.setDesc(EdgeStrategyTypeEnum.REVERSE_POWER.getDesc());
            edgeStrategyRequestVO.setData(reversePower);
        }else if(type.equals(EnergyScheduleType.SOC_CONTROL.getCode())){
            /**
             * 进入SOC控制下发
             */
            EdgeStrategySocControl socControl = new EdgeStrategySocControl();
            socControl.setSocUpper(emsEnergyScheduleRequestVO.getSocUpper());
            socControl.setSocLower(emsEnergyScheduleRequestVO.getSocLower());
            socControl.setUsableSocUpper(emsEnergyScheduleRequestVO.getSocUpper());
            socControl.setUsableSocLower(emsEnergyScheduleRequestVO.getUsableSocLower());
            socControl.setEnableInputSocMaintain(emsEnergyScheduleRequestVO.getEnableInputSocMaintain());

            edgeStrategyRequestVO.setEnable(emsEnergyScheduleRequestVO.getSocControlEnabled());
            edgeStrategyRequestVO.setType(EdgeStrategyTypeEnum.SOC_CONTROL.getCode());
            edgeStrategyRequestVO.setDesc(EdgeStrategyTypeEnum.SOC_CONTROL.getDesc());
            edgeStrategyRequestVO.setData(socControl);
        }
        return edgeStrategyRequestVO;
    }

    public EdgeStrategyRequestVO setEnergyScheduleEnableReportedVO(String energyStationId, String energyEquipmentId, Integer enabled , Integer type){
        EdgeStrategyRequestVO edgeStrategyRequestVO = new EdgeStrategyRequestVO();
        EmsEnergySchedule energySchedule = emsEnergyScheduleDAO.getByStationIdByEquipmentId(energyStationId, energyEquipmentId);
        if(type.equals(EnergyScheduleType.DEMAND_CONTROL.getCode())){
            EdgeStrategyDemandControl demandControl = new EdgeStrategyDemandControl();
            demandControl.setDemandValue(energySchedule.getDemandValue());
            demandControl.setOverDemandPercent(energySchedule.getOverDemandPercent());
            demandControl.setDischargePower(energySchedule.getDischargePower());

            edgeStrategyRequestVO.setEnable(enabled);
            edgeStrategyRequestVO.setType(EdgeStrategyTypeEnum.DEMAND_CONTOL.getCode());
            edgeStrategyRequestVO.setDesc(EdgeStrategyTypeEnum.DEMAND_CONTOL.getDesc());
            edgeStrategyRequestVO.setData(demandControl);
        }else if(type.equals(EnergyScheduleType.BACKUP_POWER.getCode())){
            EdgeStrategyBatteryReserved batteryReserved = new EdgeStrategyBatteryReserved();
            batteryReserved.setBatteryReservedCapacity(energySchedule.getBatteryReservedCapacity());

            edgeStrategyRequestVO.setEnable(enabled);
            edgeStrategyRequestVO.setType(EdgeStrategyTypeEnum.BATTERY_RESERVED.getCode());
            edgeStrategyRequestVO.setDesc(EdgeStrategyTypeEnum.BATTERY_RESERVED.getDesc());
            edgeStrategyRequestVO.setData(batteryReserved);
        }else if(type.equals(EnergyScheduleType.INVERSE_POWER_OUTPUT.getCode())){
            EdgeStrategyReversePower reversePower = new EdgeStrategyReversePower();
            reversePower.setInversePowerMinPower(energySchedule.getInversePowerMinPower());

            edgeStrategyRequestVO.setEnable(enabled);
            edgeStrategyRequestVO.setType(EdgeStrategyTypeEnum.REVERSE_POWER.getCode());
            edgeStrategyRequestVO.setDesc(EdgeStrategyTypeEnum.REVERSE_POWER.getDesc());
            edgeStrategyRequestVO.setData(reversePower);
        }else if(type.equals(EnergyScheduleType.SOC_CONTROL.getCode())){
            EdgeStrategySocControl socControl = new EdgeStrategySocControl();
            socControl.setSocUpper(energySchedule.getSocUpper());
            socControl.setSocLower(energySchedule.getSocLower());
            socControl.setUsableSocUpper(energySchedule.getUsableSocUpper());
            socControl.setUsableSocLower(energySchedule.getUsableSocLower());
            socControl.setEnableInputSocMaintain(energySchedule.getEnableInputSocMaintain());

            edgeStrategyRequestVO.setEnable(enabled);
            edgeStrategyRequestVO.setType(EdgeStrategyTypeEnum.SOC_CONTROL.getCode());
            edgeStrategyRequestVO.setDesc(EdgeStrategyTypeEnum.SOC_CONTROL.getDesc());
            edgeStrategyRequestVO.setData(socControl);
        }
        return edgeStrategyRequestVO;
    }

    public EdgeStrategyRequestVO setEmsPeakShiftReportedVO(EmsPeakShiftRequestVO emsPeakShiftRequestVO){
        List<EmsPeakShiftDetail> emsPeakShiftDetails = EmsPeakShiftDetailDO.requestVOListToEntityList(emsPeakShiftRequestVO.getEmsPeakShiftDetailRequestVOS());
        List<EdgeStrategyPeakValleyBalance> valleyBalanceList = Lists.newArrayList();
        for(EmsPeakShiftDetail emsPeakShiftDetail:emsPeakShiftDetails){
            EdgeStrategyPeakValleyBalance valleyBalance = new EdgeStrategyPeakValleyBalance();
            valleyBalance.setVal(emsPeakShiftDetail.getPower());
            valleyBalance.setTime(emsPeakShiftDetail.getStartTime());
            valleyBalanceList.add(valleyBalance);
        }
        EdgeStrategyRequestVO edgeStrategyRequestVO = new EdgeStrategyRequestVO();
        edgeStrategyRequestVO.setEnable(emsPeakShiftRequestVO.getPeakShiftEnabled());
        edgeStrategyRequestVO.setType(EdgeStrategyTypeEnum.PEAK_VALLEY_BALANCE.getCode());
        edgeStrategyRequestVO.setDesc(EdgeStrategyTypeEnum.PEAK_VALLEY_BALANCE.getDesc());
        edgeStrategyRequestVO.setData(valleyBalanceList);
        return edgeStrategyRequestVO;
    }

    public EdgeStrategyRequestVO setEmsPeakShiftEnableReportedVO(String peakShiftId, Integer enabled){
        List<EmsPeakShiftDetail> listByPeakShiftId = emsPeakShiftDetailDAO.getListByPeakShiftId(peakShiftId);
        EmsPeakShift peakShift = emsPeakShiftDAO.getById(peakShiftId);
        List<EdgeStrategyPeakValleyBalance> valleyBalanceList = Lists.newArrayList();
        listByPeakShiftId.stream().forEach(d->{
            EdgeStrategyPeakValleyBalance valleyBalance = new EdgeStrategyPeakValleyBalance();
            valleyBalance.setVal(d.getPower());
            valleyBalance.setTime(d.getStartTime());
            valleyBalanceList.add(valleyBalance);
        });
        EdgeStrategyRequestVO edgeStrategyRequestVO = new EdgeStrategyRequestVO();
        edgeStrategyRequestVO.setEnable(peakShift.getPeakShiftEnabled());
        edgeStrategyRequestVO.setType(EdgeStrategyTypeEnum.PEAK_VALLEY_BALANCE.getCode());
        edgeStrategyRequestVO.setDesc(EdgeStrategyTypeEnum.PEAK_VALLEY_BALANCE.getDesc());
        edgeStrategyRequestVO.setData(valleyBalanceList);
        return edgeStrategyRequestVO;
    }

    public List<EmsPeakShiftDetail> sortEmsPeakShiftDetail(List<EmsPeakShiftDetail> emsPeakShiftDetails){
        for (int i = 0; i < emsPeakShiftDetails.size()-1; i++) {
            for (int j = 0; j < emsPeakShiftDetails.size()-1-i; j++) {
                if (emsPeakShiftDetails.get(j).getStartTime() > emsPeakShiftDetails.get(j+1).getStartTime()) {
                    EmsPeakShiftDetail stu = emsPeakShiftDetails.get(j);
                    emsPeakShiftDetails.set(j, emsPeakShiftDetails.get(j+1));
                    emsPeakShiftDetails.set(j+1, stu );
                }
            }
        }
        return emsPeakShiftDetails;
    }
}
